﻿using TrueSync;
using TrueSync.Physics2D;
using Network;
using Framework;

public class LogicMoveComponent : LogicComponent
{
    FightCharacter mLEntity;
    TSVector2 mPosition;
    Fixture mBodyRect;
    public TSVector2 Position
    {
        get
        {
            return mPosition;
        }
        set
        {
            mPosition = value;
            mLEntity.SendEntityMessage((int)L2VMsgId.SetPosition, mPosition);
        }
    }

    public TSTransform Transform
    {
        get
        {
            return new TSTransform(mPosition, new Rot(0), FaceDirection == -1);
        }
    }

    public TSVector2 MoveSpeed
    {
        get;set; 
    }

    int mFaceDirection;
    public int FaceDirection
    {
        get
        {
            return mFaceDirection;
        }

        set
        {
            if (value != mFaceDirection)
            {
                mFaceDirection = value;
                mLEntity.SendEntityMessage((int)L2VMsgId.SetFaceDirection, mFaceDirection);
            }
        }
    }

    FP mHitbackLength;//这个值大于0的时候表示正在被击退,如果移到版边要去给对方移动
    public bool IsHittingBack
    {
        get
        {
            return mHitbackLength > 0;
        }
    }

    public TSVector2 TargetPoint;

    public void Init(LogicEntity LEntity)
    {
        mLEntity = (FightCharacter)LEntity;
        mHitbackLength = 0;
    }

    public void Start()
    {
        LogicPhysicsComponent physicsComponent = mLEntity.GetLogicComponent<LogicPhysicsComponent>();
        mBodyRect = physicsComponent.BodyPositionRect;
        mBodyRect.OnCollision += OnBodyRectCollision;
    }

    public void DoUpdate(FP deltaTime)
    {
        //重力
        MoveSpeed += Settings.Gravity;
        //位移
        Position += MoveSpeed;
        if(Position.y < 0)
        {
            Position = new TSVector2(Position.x, 0);
            MoveSpeed = new TSVector2(MoveSpeed.x, 0);
        }

        //解决场景边界
        FP scenebackBorderLen = GetSceneBackBorderLen();
        if(scenebackBorderLen < 0)
        {
            Position += new TSVector2(FaceDirection * -scenebackBorderLen, 0);
            //在击退中而且自己的位置不够用了就去推对方
            if(IsHittingBack)
            {
                ObjHandle<LogicEntity> rival = FightGame.Instance.GetRivalEntity(mLEntity.PlayerID);
                rival.handle.GetLogicComponent<LogicMoveComponent>().Position += new TSVector2(FaceDirection * -scenebackBorderLen, 0);
            }
        }

        FP sceneFrontBorderLen = GetSceneFrontBorderLen();
        if (sceneFrontBorderLen < 0)
        {
            Position += new TSVector2(FaceDirection * scenebackBorderLen, 0);
        }

        if (mHitbackLength > 0)
        {
            mHitbackLength -= FP.FastAbs(MoveSpeed.x);
            if(mHitbackLength <= 0)
            {
                //击退距离到了
                MoveSpeed = new TSVector2(0, MoveSpeed.y);
            }
        }
    }

    //专门弄出来这个就是为了版边击退对方其实自己在后退
    public void Hitback(FP length, FP speed)
    {
        mHitbackLength = length;
        MoveSpeed = new TSVector2(speed, 0);
    }

    public void HitbackFinish()
    {
        mHitbackLength = 0;
    }

    void OnBodyRectCollision(Fixture self, Fixture other)
    {
        //计算穿插距离
        FP selfX = Position.x;
        FP selfFrontLen = ((RectangleShape)self.Shape).max.x;
        ObjHandle<LogicEntity> otherEntity = (ObjHandle<LogicEntity>)other.UserData;
        LogicMoveComponent otherMoveComponent = otherEntity.handle.GetLogicComponent<LogicMoveComponent>();
        FP otherX = otherMoveComponent.Position.x;
        FP otherFrontLen = ((RectangleShape)other.Shape).max.x;
        FP intersectLen = FP.FastAbs(selfX + selfFrontLen - (otherX + otherFrontLen));
        if(intersectLen > 0)
        {
            //双方根据穿插距离各退半步加
            FP halfIntersectLen = intersectLen / 2;
            FP otherBorderLenAfterDisplace = otherMoveComponent.GetSceneBackBorderLen() - halfIntersectLen;
            if(otherBorderLenAfterDisplace < 0)
            {
                //如果对方移动后出了场景边界,超出的距离放到自己身上作位移
                halfIntersectLen -= otherBorderLenAfterDisplace;
            }
            FP myBorderLenAfterDisplace = GetSceneBackBorderLen() - halfIntersectLen;
            if(myBorderLenAfterDisplace < 0)
            {
                //如果我移动以后出了场景边界,强行把自己拉回来
                halfIntersectLen += myBorderLenAfterDisplace;
            }

            Position -= new TSVector2(FaceDirection * halfIntersectLen, 0);
        }
    }

    public void Destroy()
    {
        mBodyRect.OnCollision -= OnBodyRectCollision;
        mBodyRect = null;
    }

    public void FaceOther()//面向对方
    {
        if (mLEntity.mRival.IsValid == false)
            return;

        if (Position.x <= mLEntity.mRival.handle.GetLogicComponent<LogicMoveComponent>().Position.x)
            FaceDirection = 1;
        else
            FaceDirection = -1;
    }

    public FP GetSceneBackBorderLen()
    {
        if(FaceDirection == 1)
        {
            return Position.x + ((RectangleShape)mBodyRect.Shape).min.x - FightGame.Instance.MinSceneX;
        }
        else
        {
            return FightGame.Instance.MaxSceneX - (Position.x + ((RectangleShape)mBodyRect.Shape).min.x);
        }
    }

    public FP GetSceneFrontBorderLen()
    {
        if (FaceDirection == 1)
        {
            return FightGame.Instance.MaxSceneX - (Position.x + ((RectangleShape)mBodyRect.Shape).max.x);
        }
        else
        {
            return Position.x + ((RectangleShape)mBodyRect.Shape).min.x - FightGame.Instance.MinSceneX;
        }
    }
}
